package biz.datalk.industrialland.common.json;

import biz.datalk.industrialland.common.json.annotation.Json;
import biz.datalk.industrialland.common.result.UnifyResult;
import biz.datalk.industrialland.common.util.SpringContextUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author tarofang@163.com
 * @date 2019-08-19
 */
public class CustomerJsonSerializer {
    private ObjectMapper mapper = null;
    private JacksonJsonFilter jacksonFilter = new JacksonJsonFilter();

    public CustomerJsonSerializer() {
        try {
            ObjectMapper objMapper = SpringContextUtils.getBean(ObjectMapper.class);
            mapper = objMapper.copy();
        } catch (Exception ex) {
            mapper = new ObjectMapper();
        }
    }

    /**
     * @param clazz target type
     * @param include include fields
     * @param filter filter fields
     */
    public void filter(Class<?> clazz, String include, String filter) {
        if (clazz == null) {
            return;
        }
        if (!StringUtils.isEmpty(include)) {
            jacksonFilter.include(clazz, include.split(","));
        }
        if (!StringUtils.isEmpty(filter)) {
            jacksonFilter.filter(clazz, filter.split(","));
        }
        mapper.addMixIn(clazz, jacksonFilter.getClass());
    }

    public String toJson(Object object) throws JsonProcessingException {
        mapper.setFilterProvider(jacksonFilter);
        return mapper.writeValueAsString(object);
    }
    public void filter(Json json) {
        this.filter(json.type(), json.include(), json.filter());
    }

    /**
     * 用于测试自定义是否起作用
     * @param args
     * @throws JsonProcessingException
     */
    public static void main(String args[]) throws JsonProcessingException {

        CustomerJsonSerializer cjs= new CustomerJsonSerializer();
        cjs.filter(MyTest.class, "name,age", null);
        String include = cjs.toJson(new MyTest());

        cjs = new CustomerJsonSerializer();
        cjs.filter(MyTest.class, null, "name");
        String filter = cjs.toJson(new MyTest());

        System.out.println("include: " + include);
        System.out.println("filter: " + filter);

        List<MyTest> resList = new ArrayList<>();
        resList.add(new MyTest());
        UnifyResult result = UnifyResult.success();
        result.mapData().put("a", resList);

        cjs = new CustomerJsonSerializer();
        cjs.filter(MyTest.class, null, "name");
        System.out.println(cjs.toJson(result));
    }
}
